package edu.kit.aifb.ldstream.learner.dao;

import java.io.Serializable;

import org.openrdf.model.URI;
import org.openrdf.model.impl.URIImpl;

import edu.kit.aifb.ldstream.stat.distrib.IDistribution;

public class Type extends URIImpl implements Serializable, Comparable<Type>{


	private static final long serialVersionUID = -245675008425793616L;

	private URI uri;
	
	private double coverage;
	private double weight;
	private double linkageDegree;
	
	private IDistribution outdegreeDistribution;
	private IDistribution indegreeDistribution;
	
	transient private int numProps = 0;
	
	public Type(URI uri){
		super(uri.stringValue());
		this.uri = uri;
	}
	
	public URI getURI(){
		return this.uri;
	}
	
	public void setNumProperties(int num){
		this.numProps = num;
	}
	
	public void setCoverageWeight(double w){
		if(w < 0 || w > 1) {
			throw new IllegalArgumentException("CoverageWeight must be between 0 and 1");
		}
		this.weight = w;
	}
	
	public double getCoverageWeight(){
		return this.weight;
	}
	
	public void setCoverage(double cv){
		if(cv < 0 || cv > 1) {
			throw new IllegalArgumentException("Coverage must be between 0 and 1");
		}
		this.coverage = cv;
	}
	
	public double getCoverage(){
		return this.coverage;
	}
	public int getNumProps(){
		return this.numProps;
	}
	
	public boolean equals(Object o){
		
		// checking for instanceof URI is a later on "improvement" URIImpl should be subclassed
		// but then several changes would be necessary
		if(o instanceof URI){
			return this.uri.equals((URI) o);
		}

		return false;
	}
	
	public int hashCode(){
		return this.uri.hashCode();
	}
	
	public String toString(){
		return this.uri.toString();
	}

	/**
	 * @param outdegreeDistribution the outdegreeDistribution to set
	 */
	public void setOutdegreeDistribution(IDistribution outdegreeDistribution) {
		this.outdegreeDistribution = outdegreeDistribution;
	}

	/**
	 * @param indegreeDistribution the indegreeDistribution to set
	 */
	public void setIndegreeDistribution(IDistribution indegreeDistribution) {
		this.indegreeDistribution = indegreeDistribution;
	}

	/**
	 * @return the linkageDegree
	 */
	public double getLinkageDegree() {
		return linkageDegree;
	}

	/**
	 * @param linkageDegree the linkageDegree to set
	 */
	public void setLinkageDegree(double linkageDegree) {
		if(linkageDegree < 0 || linkageDegree > 1){
			throw new IllegalArgumentException("LinkageDegree must be between [0,1]");
		}
		this.linkageDegree = linkageDegree;
	}



	/**
	 * @return the weight
	 */
	public double getWeight() {
		return weight;
	}

	/**
	 * @return the outdegreeDistribution
	 */
	public IDistribution getOutdegreeDistribution() {
		return outdegreeDistribution;
	}

	/**
	 * @return the indegreeDistribution
	 */
	public IDistribution getIndegreeDistribution() {
		return indegreeDistribution;
	}

	@Override
	public int compareTo(Type o) {
		return this.uri.stringValue().compareTo(o.getURI().stringValue());
	}
}
